import type { AppRouteRecordRaw, Menu } from '/@/router/types';
import { setAuthCache } from '/@/utils/auth';
import { TOKEN_KEY } from '/@/enums/cacheEnum';
import { defineStore } from 'pinia';
import { store } from '/@/store';
import { useI18n } from '/@/hooks/web/useI18n';
import { useUserStore } from './user';
import { useAppStoreWithOut } from './app';
import { toRaw } from 'vue';
import { transformObjToRoute, flatMultiLevelRoutes, addSlashToRouteComponent } from '/@/router/helper/routeHelper';
import { transformRouteToMenu } from '/@/router/helper/menuHelper';

import projectSetting from '/@/settings/projectSetting';

import { PermissionModeEnum } from '/@/enums/appEnum';

import { asyncRoutes } from '/@/router/routes';
import { ERROR_LOG_ROUTE, PAGE_NOT_FOUND_ROUTE } from '/@/router/routes/basic';

import { filter } from '/@/utils/helper/treeHelper';

import { getMenuList, switchVue3Menu } from '/@/api/sys/menu';
import { getPermCode } from '/@/api/sys/user';

import { useMessage } from '/@/hooks/web/useMessage';
import { PageEnum } from '/@/enums/pageEnum';

// import { useMenuSetting } from "/@/hooks/setting/useMenuSetting";
// const { getShowMenu, setMenuSetting } = useMenuSetting();
// import { useHeaderSetting } from "/@/hooks/setting/useHeaderSetting";
// const { setHeaderSetting } = useHeaderSetting();
// import { useMultipleTabSetting } from "/@/hooks/setting/useMultipleTabSetting";
// const { setMultipleTabSetting } = useMultipleTabSetting();

// 系统权限
interface AuthItem {
	// 菜单权限编码，例如：“sys:schedule:list,sys:schedule:info”,多个逗号隔开
	action: string;
	// 权限策略1显示2禁用
	type: string | number;
	// 权限状态(0无效1有效)
	status: string | number;
	// 权限名称
	describe?: string;
	isAuth?: boolean;
}

interface PermissionState {
	// Permission code list
	permCodeList: string[] | number[];
	// Whether the route has been dynamically added
	isDynamicAddedRoute: boolean;
	// To trigger a menu update
	lastBuildMenuTime: number;
	// Backstage menu list
	backMenuList: Menu[];
	frontMenuList: Menu[];
	// 用户所拥有的权限
	authList: AuthItem[];
	// 全部权限配置
	allAuthList: AuthItem[];
	// 系统安全模式
	sysSafeMode: boolean;
	// online子表按钮权限
	onlineSubTableAuthMap: object;
}
export const usePermissionStore = defineStore({
	id: 'app-permission',
	state: (): PermissionState => ({
		permCodeList: [],
		// Whether the route has been dynamically added
		isDynamicAddedRoute: true,
		// To trigger a menu update
		lastBuildMenuTime: 0,
		// Backstage menu list
		backMenuList: [],
		// menu List
		frontMenuList: [],
		authList: [],
		allAuthList: [],
		sysSafeMode: false,
		onlineSubTableAuthMap: {},
	}),
	getters: {
		getPermCodeList(): string[] | number[] {
			return this.permCodeList;
		},
		getBackMenuList(): Menu[] {
			return this.backMenuList;
		},
		getFrontMenuList(): Menu[] {
			return this.frontMenuList;
		},
		getLastBuildMenuTime(): number {
			return this.lastBuildMenuTime;
		},
		getIsDynamicAddedRoute(): boolean {
			return this.isDynamicAddedRoute;
		},

		//update-begin-author:taoyan date:2022-6-1 for: VUEN-1162 子表按钮没控制
		getOnlineSubTableAuth: (state) => {
			return (code) => state.onlineSubTableAuthMap[code];
		},
		//update-end-author:taoyan date:2022-6-1 for: VUEN-1162 子表按钮没控制
	},
	actions: {
		setPermCodeList(codeList: string[]) {
			this.permCodeList = codeList;
		},

		setBackMenuList(list: Menu[]) {
			this.backMenuList = list;
			list?.length > 0 && this.setLastBuildMenuTime();
		},

		setFrontMenuList(list: Menu[]) {
			this.frontMenuList = list;
		},

		setLastBuildMenuTime() {
			this.lastBuildMenuTime = new Date().getTime();
		},

		setDynamicAddedRoute(added: boolean) {
			this.isDynamicAddedRoute = added;
		},
		resetState(): void {
			this.isDynamicAddedRoute = false;
			this.permCodeList = [];
			this.backMenuList = [];
			this.lastBuildMenuTime = 0;
		},
		async changePermissionCode() {
			const systemPermission = await getPermCode();
			const codeList = systemPermission.data.codeList;
			this.setPermCodeList(codeList);
			this.setAuthData(systemPermission.data);
		},
		async buildRoutesAction(): Promise<AppRouteRecordRaw[]> {
			const { t } = useI18n();
			const userStore = useUserStore();
			const appStore = useAppStoreWithOut();
			let routes: AppRouteRecordRaw[] = [];
			const roleList = toRaw(userStore.getRoleList) || [];
			const { permissionMode = projectSetting.permissionMode } = appStore.getProjectConfig;

			const routeFilter = (route: AppRouteRecordRaw) => {
				const { meta } = route;
				const { roles } = meta || {};
				if (!roles) return true;
				return roleList.some((role) => roles.includes(role));
			};

			const routeRemoveIgnoreFilter = (route: AppRouteRecordRaw) => {
				const { meta } = route;
				const { ignoreRoute } = meta || {};
				return !ignoreRoute;
			};

			/**
			 * @description 根据设置的首页path，修正routes中的affix标记（固定首页）
			 * */
			const patchHomeAffix = (routes: AppRouteRecordRaw[]) => {
				if (!routes || routes.length === 0) return;
				let homePath: string = userStore.getUserInfo.homePath || PageEnum.BASE_HOME;
				function patcher(routes: AppRouteRecordRaw[], parentPath = '') {
					if (parentPath) parentPath = parentPath + '/';
					routes.forEach((route: AppRouteRecordRaw) => {
						const { path, children, redirect } = route;
						const currentPath = path.startsWith('/') ? path : parentPath + path;
						if (currentPath === homePath) {
							if (redirect) {
								homePath = route.redirect! as string;
							} else {
								route.meta = Object.assign({}, route.meta, { affix: true });
								throw new Error('end');
							}
						}
						children && children.length > 0 && patcher(children, currentPath);
					});
				}
				try {
					patcher(routes);
				} catch (e) {
					// 已处理完毕跳出循环
				}
				return;
			};

			switch (permissionMode) {
				case PermissionModeEnum.ROLE:
					routes = filter(asyncRoutes, routeFilter);
					routes = routes.filter(routeFilter);
					//  将多级路由转换为二级
					routes = flatMultiLevelRoutes(routes);
					break;

				case PermissionModeEnum.ROUTE_MAPPING:
					routes = filter(asyncRoutes, routeFilter);
					routes = routes.filter(routeFilter);
					const menuList = transformRouteToMenu(routes, true);
					routes = filter(routes, routeRemoveIgnoreFilter);
					routes = routes.filter(routeRemoveIgnoreFilter);
					menuList.sort((a, b) => {
						return (a.meta?.orderNo || 0) - (b.meta?.orderNo || 0);
					});

					this.setFrontMenuList(menuList);
					// 将多级路由转换为二级
					routes = flatMultiLevelRoutes(routes);
					break;

				// 后台菜单构建
				case PermissionModeEnum.BACK:
					const { createMessage, createWarningModal } = useMessage();
					// 菜单加载提示
					createMessage.loading({
						content: t('sys.app.menuLoading'),
						duration: 1,
					});



					// 从后台获取权限码，
					// 这个函数可能只需要执行一次，并且实际的项目可以在正确的时间被放置
					let routeList: AppRouteRecordRaw[] = [];
					try {
						this.changePermissionCode();
						routeList = (await getMenuList()) as AppRouteRecordRaw[];
						// update-begin----author:sunjianlei---date:20220315------for: 判断是否是 vue3 版本的菜单 ---
						let hasIndex: boolean = false;
						let hasIcon: boolean = false;
						for (let menuItem of routeList) {
							// 条件1：判断组件是否是 layouts/default/index
							if (!hasIndex) {
								hasIndex = menuItem.component === 'layouts/default/index';
							}
							// 条件2：判断图标是否带有 冒号
							if (!hasIcon) {
								hasIcon = !!menuItem.meta?.icon?.includes(':');
							}
							// 满足任何一个条件都直接跳出循环
							if (hasIcon || hasIndex) {
								break;
							}
						}
						// 两个条件都不满足，就弹出提示框
						if (!hasIcon && !hasIndex) {
							// 延迟1.5秒之后再出现提示，否则提示框出不来
							setTimeout(
								() => {
									localStorage.clear()
									setAuthCache(TOKEN_KEY, null);
									location.reload()
								},
								100
							);
						}
						// update-end----author:sunjianlei---date:20220315------for: 判断是否是 vue3 版本的菜单 ---
					} catch (error) {
						console.error(error);
					}
					// 组件地址前加斜杠处理  author: lsq date:2021-09-08
					routeList = addSlashToRouteComponent(routeList);
					// 动态引入组件
					routeList = transformObjToRoute(routeList);
					// 构建后台路由菜单
					const backMenuList = transformRouteToMenu(routeList);
					this.setBackMenuList(backMenuList);

					// 删除meta.ignoreRoute项
					routeList = filter(routeList, routeRemoveIgnoreFilter);
					routeList = routeList.filter(routeRemoveIgnoreFilter);
					routeList = flatMultiLevelRoutes(routeList);
					routes = [PAGE_NOT_FOUND_ROUTE, ...routeList];
					break;
			}
			routes.push(ERROR_LOG_ROUTE);
			// patchHomeAffix(routes);
			return routes;
		},
		setAuthData(systemPermission) {
			this.authList = systemPermission.auth;
			this.allAuthList = systemPermission.allAuth;
			this.sysSafeMode = systemPermission.sysSafeMode;
		},
		setAuthList(authList: AuthItem[]) {
			this.authList = authList;
		},
		setAllAuthList(authList: AuthItem[]) {
			this.allAuthList = authList;
		},

		//update-begin-author:taoyan date:2022-6-1 for: VUEN-1162 子表按钮没控制
		setOnlineSubTableAuth(code, hideBtnList) {
			this.onlineSubTableAuthMap[code] = hideBtnList;
		},
		//update-end-author:taoyan date:2022-6-1 for: VUEN-1162 子表按钮没控制
	},
});

// 需要在设置之外使用
export function usePermissionStoreWithOut() {
	return usePermissionStore(store);
}
